'use strict';

const { Controller } = require('egg');
const path = require('path')
const fs = require('fs')
// 文件存储目录
const uploadFilePath = path.resolve(__dirname, '../../uploadFile');

class HomeController extends Controller {
  async uploadImage() {
    // 获取上下文
    const { ctx } = this;
    // 获取发送过来的文件信息
    const file = ctx.request.files[0];
    // 获取文件路径
    const filepath = file.filepath
    ctx.body = {
      code: 200,
      message: '上传成功',
      data: {
        // 返回网络路径
        url: 'http://localhost:7001/' + filepath.slice(filepath.indexOf('public'))
      }
    };
  }
  async checkFile() {
    const { ctx } = this;
    // 1. 获取 hash
    const { hash, extName } = ctx.request.body
    // 2. 获取服务器上的hash
    const dirs = await fs.promises.readdir(uploadFilePath)
    // 3. 验证文件是否存在
    const name = (hash + extName)

    const isExist = dirs.some(v => v === name)
    // 4. 返回对应结果
    // 4-1 检查文件存在
    if (isExist) {
      // 文件存在， 说明已经上传过了， 不需要再次上传， 直接成功。
      ctx.body = {
        code: 200,
        message: '文件秒传成功！',
        uploaded: true
      }
    } else {
      // 文件不存在
      // 文件夹是否存在
      const isExistDir = dirs.some(v => v === hash);

      if (isExistDir) {
        // 文件夹存在， 说明用户曾经上传过一部分，返回已经上传过得文件切片。
        const targetDir = path.join(uploadFilePath, hash)
        // 
        ctx.body = {
          code: 200,
          message: '请继续上传',
          uploaded: await fs.promises.readdir(targetDir)
        }
      } else {
        // 文件夹不存在， 说明是新的文件， 服务器并没有， 直接开始上传即可
        ctx.body = {
          code: 200,
          message: '请开始上传文件',
          uploaded: false
        }
      }

    }

  }
  async upload() {
    const { ctx } = this;
    const file = ctx.request.files[0];
    // 获取文件名字
    const filename = file.filename
    // 获取文件路径
    const filepath = file.filepath
    // 获取文件hash
    const hash = filename.split('-')[0]
    try {
      // 切片文件夹
      const hashDir = path.join(uploadFilePath, hash);
      // 切片文件夹是否存在， 不存在就创建文件夹
      if (!fs.existsSync(hashDir)) {
        await fs.promises.mkdir(hashDir)
      }
      // 将文件复制到 指定文件夹目录
      await fs.promises.copyFile(filepath, path.join(hashDir, filename))
    } finally {
      // 删除临时文件
      ctx.cleanupRequestFiles();
    }

    ctx.body = {
      code: 200
    };
  }
  async mergeFile() {
    const { ctx } = this;
    const { hash, extName } = ctx.request.body;
    const hashDir = path.join(uploadFilePath, hash);
    if (fs.existsSync(hashDir)) {
      // 读取子目录， 并排序
      const hashDirChildren = (await fs.promises.readdir(hashDir)).sort((a, b) => {
        // '357c12c4ba00686ebb4ac17ccfa61715-13.mp4'
        // 获取正确的切片顺序
        const aIndex = a.slice(a.indexOf('-') + 1, a.indexOf('.'));
        const bIndex = b.slice(b.indexOf('-') + 1, b.indexOf('.'))
        return aIndex - bIndex
      }).map(v => {
        // 拼接父级目录
        return path.join(hashDir, v)
      });
      // 容器
      const arr = []
      // 数据总大小
      let len = 0
      hashDirChildren.forEach(v => {
        // 读取切片文件
        const data = fs.readFileSync(v)
        // 存储
        arr.push(data);
        // 计算大小
        len += data.length
      })
      // 写入文件
      fs.writeFileSync(path.join(hashDir, hash + extName), Buffer.concat(arr, len))

      ctx.body = {
        message: '合并文件成功',
        code: 200
      }
    } else {
      ctx.body = {
        message: '合并的文件不存在',
        code: 400
      }
    }
  }
}

module.exports = HomeController;
